<!DOCTYPE html>



  


<html class="theme-next mist use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Hexo, NexT" />










<meta name="description" content="说道spring的web支持首先就可以想到了spring MVC 的技术(其他的技术还有spring的webflux 以后讨论),从这片博客开始要进行相关知识点的整理. spring MVC 整体的架构设计 spring 自己的webapplication支持嵌套作用域,通过这个方法可以实现spring applicationcongtext的继承特性(继承特性,子作用域可以访问夫作用域的中的属性">
<meta property="og:type" content="article">
<meta property="og:title" content="kyssion-blog">
<meta property="og:url" content="http://yoursite.com/2018/10/09/javaEE servlet3.1规范/index.html">
<meta property="og:site_name" content="kyssion-blog">
<meta property="og:description" content="说道spring的web支持首先就可以想到了spring MVC 的技术(其他的技术还有spring的webflux 以后讨论),从这片博客开始要进行相关知识点的整理. spring MVC 整体的架构设计 spring 自己的webapplication支持嵌套作用域,通过这个方法可以实现spring applicationcongtext的继承特性(继承特性,子作用域可以访问夫作用域的中的属性">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="http://yoursite.com/blogimg/springMVC/1.jpg">
<meta property="og:image" content="http://yoursite.com/blogimg/1.png">
<meta property="og:updated_time" content="2018-10-09T07:22:37.337Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="kyssion-blog">
<meta name="twitter:description" content="说道spring的web支持首先就可以想到了spring MVC 的技术(其他的技术还有spring的webflux 以后讨论),从这片博客开始要进行相关知识点的整理. spring MVC 整体的架构设计 spring 自己的webapplication支持嵌套作用域,通过这个方法可以实现spring applicationcongtext的继承特性(继承特性,子作用域可以访问夫作用域的中的属性">
<meta name="twitter:image" content="http://yoursite.com/blogimg/springMVC/1.jpg">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Mist',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://yoursite.com/2018/10/09/javaEE servlet3.1规范/"/>





  <title> | kyssion-blog</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">kyssion-blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-schedule">
          <a href="/schedule/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-calendar"></i> <br />
            
            日程表
          </a>
        </li>
      
        
        <li class="menu-item menu-item-sitemap">
          <a href="/sitemap.xml" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-sitemap"></i> <br />
            
            站点地图
          </a>
        </li>
      
        
        <li class="menu-item menu-item-commonweal">
          <a href="/404/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-heartbeat"></i> <br />
            
            公益404
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/09/javaEE servlet3.1规范/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="kyssion">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="kyssion-blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline"></h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-10-09T15:22:37+08:00">
                2018-10-09
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>说道spring的web支持首先就可以想到了spring MVC 的技术(其他的技术还有spring的webflux 以后讨论),从这片博客开始要进行相关知识点的整理.</p>
<h3 id="spring-MVC-整体的架构设计"><a href="#spring-MVC-整体的架构设计" class="headerlink" title="spring MVC 整体的架构设计"></a>spring MVC 整体的架构设计</h3><p><img src="/blogimg/springMVC/1.jpg" alt=""></p>
<p>spring 自己的webapplication支持嵌套作用域,通过这个方法可以实现spring applicationcongtext的继承特性(继承特性,子作用域可以访问夫作用域的中的属性,但是父作用域中的属性无法访问子作用域中的属性,具体的使用看HierarchicalBeanFactory)</p>
<h4 id="web容器的初始化设置"><a href="#web容器的初始化设置" class="headerlink" title="web容器的初始化设置"></a>web容器的初始化设置</h4><p>springMVC 支持使用xml进行配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">web-app</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">listener</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">listener-class</span>&gt;</span>org.springframework.web.context.ContextLoaderListener<span class="tag">&lt;/<span class="name">listener-class</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">listener</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">context-param</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>contextConfigLocation<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>/WEB-INF/app-context.xml<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">context-param</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">servlet</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>app<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-class</span>&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="tag">&lt;/<span class="name">servlet-class</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>contextConfigLocation<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">param-value</span>&gt;</span><span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">load-on-startup</span>&gt;</span>1<span class="tag">&lt;/<span class="name">load-on-startup</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">servlet</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>app<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/app/*<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">web-app</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>从spring5.0 开始 spring官方文档提倡使用接口配置,容器在初始化的时候将会自动的加载这个接口的实现类从而进行配置<br>spring mvc 的自动化配置是通过 WebApplicationInitializer 接口实现的 但是系统提供了更加高级的接口 AbstractAnnotationConfigDispatcherServletInitializer </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyWebAppInitializer</span> <span class="keyword">extends</span> <span class="title">AbstractAnnotationConfigDispatcherServletInitializer</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">protected</span> Class&lt;?&gt;[] getRootConfigClasses() &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Class&lt;?[] &#123; RootConfig.class &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">protected</span> Class&lt;?&gt;[] getServletConfigClasses() &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Class&lt;?[] &#123; App1Config.class &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">protected</span> String[] getServletMappings() &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> String[] &#123; <span class="string">"/app1/*"</span> &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.springframework.web.WebApplicationInitializer;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyWebApplicationInitializer</span> <span class="keyword">implements</span> <span class="title">WebApplicationInitializer</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onStartup</span><span class="params">(ServletContext container)</span> </span>&#123;</span><br><span class="line">        XmlWebApplicationContext appContext = <span class="keyword">new</span> XmlWebApplicationContext();</span><br><span class="line">        appContext.setConfigLocation(<span class="string">"/WEB-INF/spring/dispatcher-config.xml"</span>);</span><br><span class="line"></span><br><span class="line">        ServletRegistration.Dynamic registration = container.addServlet(<span class="string">"dispatcher"</span>, <span class="keyword">new</span> DispatcherServlet(appContext));</span><br><span class="line">        registration.setLoadOnStartup(<span class="number">1</span>);</span><br><span class="line">        registration.addMapping(<span class="string">"/"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>如果使用基于xml 的 spring配置则需要使用这个方法进行相关的调用</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyWebAppInitializer</span> <span class="keyword">extends</span> <span class="title">AbstractDispatcherServletInitializer</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> WebApplicationContext <span class="title">createRootApplicationContext</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> WebApplicationContext <span class="title">createServletApplicationContext</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        XmlWebApplicationContext cxt = <span class="keyword">new</span> XmlWebApplicationContext();</span><br><span class="line">        cxt.setConfigLocation(<span class="string">"/WEB-INF/spring/dispatcher-config.xml"</span>);</span><br><span class="line">        <span class="keyword">return</span> cxt;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">protected</span> String[] getServletMappings() &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> String[] &#123; <span class="string">"/"</span> &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>如果要添加filter 配置 重构如下的方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyWebAppInitializer</span> <span class="keyword">extends</span> <span class="title">AbstractDispatcherServletInitializer</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">protected</span> Filter[] getServletFilters() &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Filter[] &#123;</span><br><span class="line">            <span class="keyword">new</span> HiddenHttpMethodFilter(), <span class="keyword">new</span> CharacterEncodingFilter() &#125;;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这个方法将会为每一个filter 添加一个默认的过滤器,并且自动的添加到对应的display中</p>
<p>这个方法还有一个isisAsyncSupported() 默认情况下返回true 表示spring mvc 框架中的filter 将会异步的处理请求</p>
<blockquote>
<p>当使用idea 进行操作的时候注意要保证spring—web包要在class path目录下，不然tomcat等web 容器将不会使用spi技术将相关的各种需要的东西夹在到class中</p>
</blockquote>
<p>引申： tomcat 此处实现spi技术的解析</p>
<p>spring的web包的META-INF的文件夹中有一个名为，javax.servlet.ServletContainerInitializer的文件，其中的内容org.springframework.web.SpringServletContainerInitializer，表示定义的ServletContainerInitializer和spring的实现接口SpringServletContainerInitializer，其中@HandlesTypes注解表示CustomServletContainerInitializer 可以处理的类，在onStartup 方法中，可以通过Set&lt;Class&lt;?&gt;&gt; c 获取得到。</p>
<p>见下面代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@HandlesTypes</span>(WebApplicationInitializer.class)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringServletContainerInitializer</span> <span class="keyword">implements</span> <span class="title">ServletContainerInitializer</span> </span>&#123;</span><br><span class="line">	<span class="meta">@Override</span></span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onStartup</span><span class="params">(@Nullable Set&lt;Class&lt;?&gt;&gt; webAppInitializerClasses, ServletContext servletContext)</span></span></span><br><span class="line"><span class="function">			<span class="keyword">throws</span> ServletException </span>&#123;</span><br><span class="line">		List&lt;WebApplicationInitializer&gt; initializers = <span class="keyword">new</span> LinkedList&lt;&gt;()</span><br><span class="line">		<span class="keyword">if</span> (webAppInitializerClasses != <span class="keyword">null</span>) &#123;</span><br><span class="line">			<span class="keyword">for</span> (Class&lt;?&gt; waiClass : webAppInitializerClasses) &#123;</span><br><span class="line">				<span class="keyword">if</span> (!waiClass.isInterface() &amp;&amp; !Modifier.isAbstract(waiClass.getModifiers()) &amp;&amp;</span><br><span class="line">						WebApplicationInitializer.class.isAssignableFrom(waiClass)) &#123;</span><br><span class="line">					<span class="keyword">try</span> &#123;</span><br><span class="line">						initializers.add((WebApplicationInitializer)</span><br><span class="line">								ReflectionUtils.accessibleConstructor(waiClass).newInstance());</span><br><span class="line">					&#125;</span><br><span class="line">					<span class="keyword">catch</span> (Throwable ex) &#123;</span><br><span class="line">						<span class="keyword">throw</span> <span class="keyword">new</span> ServletException(<span class="string">"Failed to instantiate WebApplicationInitializer class"</span>, ex);</span><br><span class="line">					&#125;</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="keyword">if</span> (initializers.isEmpty()) &#123;</span><br><span class="line">			servletContext.log(<span class="string">"No Spring WebApplicationInitializer types detected on classpath"</span>);</span><br><span class="line">			<span class="keyword">return</span>;</span><br><span class="line">		&#125;</span><br><span class="line">		servletContext.log(initializers.size() + <span class="string">" Spring WebApplicationInitializers detected on classpath"</span>);</span><br><span class="line">		AnnotationAwareOrderComparator.sort(initializers);</span><br><span class="line">		<span class="keyword">for</span> (WebApplicationInitializer initializer : initializers) &#123;</span><br><span class="line">			initializer.onStartup(servletContext);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="最核心类-DispatcherServlet"><a href="#最核心类-DispatcherServlet" class="headerlink" title="最核心类 DispatcherServlet"></a>最核心类 DispatcherServlet</h3><p>如果要说这个类就需要看一下springmvc的流程图</p>
<p><img src="/blogimg/1.png" alt="">;</p>
<p>在这里之前 DispathcerServlet 将会webapplicationcontext的字符串引用放入java中 </p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + <span class="string">".CONTEXT"</span>;</span><br></pre></td></tr></table></figure>
<p>一个一个看</p>
<ol>
<li>HandlerMapping </li>
</ol>
<p>这个类解决了 url地址映射到对应的处理类中，主要有两个实现RequestMappingHandlerMapping-为@RequestMapping 注解提供支持 ，SimpleUrlHandlerMapping，实现简单的url地址映射</p>
<ol start="2">
<li>HandlerExceptionResolver </li>
</ol>
<p>这个是试图返回的异常处理包括相关的错误处理方法</p>
<ol start="3">
<li>HandlerIntercepter </li>
</ol>
<p>处理相关的接口进行拦截 </p>
<ol start="4">
<li>HandlerAdapter</li>
</ol>
<p>使用适配器模式，将试图的映射由指定的接口处理</p>
<ol start="5">
<li>各种resolver 提供视图解析展示的功能</li>
</ol>
<p>LocaleResolver, LocaleContextResolver，ThemeResolver，MultipartResolver</p>
<ol start="6">
<li>FlashMapManager</li>
</ol>
<p>处理flash的时候使用的 估计用不到了</p>
<h3 id="Interception-拦截器"><a href="#Interception-拦截器" class="headerlink" title="Interception 拦截器"></a>Interception 拦截器</h3><p>在spring MVC 中声明springmvc 的方法有如下几种：</p>
<ol>
<li>实现HandlerInterceptor接口或者实现HandlerInterceptorAdapter 抽象类</li>
<li>实现WebRequestInterceptor接口，或者实现了WebRequestInterceptor的类</li>
</ol>
<h4 id="HandlerInterceptor-接口方法"><a href="#HandlerInterceptor-接口方法" class="headerlink" title="HandlerInterceptor 接口方法"></a>HandlerInterceptor 接口方法</h4><p>(1)boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle)方法，这个将会在请求传入之前进行相关的处理，如果返回值是true，将会自动的进行链式调用其他按照顺序执行的定时器，否则将会终止调用controll和其他拦截器。</p>
<p>(2) postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,这个方法将会在处理器执行完后进行处理，和preHandle的执行方法，注意这个方法将不会自动拦截@requsetBody注解ResponseEntity</p>
<p>注意这里：（1）和（2）的第三个参数 handle 官方的解释是@controller标记的本身或者使用HandleMethod这个类，其实这里是springmvc 自己增强的方法，</p>
<blockquote>
<p>ResponseEntity 详解： 这个类其实是对 http请求的一个封装，封装了http的报头，状态码，http code 等数据，本质上是一种通信协议</p>
</blockquote>
<p>如果使用的不是string类型，那么将会是一种类似rpc协议</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//客户端</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">client</span><span class="params">()</span></span>&#123;</span><br><span class="line">    RestTemplate restTemplate = <span class="keyword">new</span> RestTemplate();</span><br><span class="line">    ResponseEntity&lt;String&gt; entity = restTemplate.getForEntity(<span class="string">"http://example.com"</span>, String.class);</span><br><span class="line">    String body = entity.getBody();</span><br><span class="line">    MediaType contentType = entity.getHeaders().getContentType();</span><br><span class="line">    HttpStatus statusCode = entity.getStatusCode();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//服务端</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/handle"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ResponseEntity&lt;String&gt; <span class="title">handle</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    URI location = ...;</span><br><span class="line">    HttpHeaders responseHeaders = <span class="keyword">new</span> HttpHeaders();</span><br><span class="line">    responseHeaders.setLocation(location);</span><br><span class="line">    responseHeaders.set(<span class="string">"MyResponseHeader"</span>, <span class="string">"MyValue"</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> ResponseEntity&lt;String&gt;(<span class="string">"Hello World"</span>, responseHeaders,   HttpStatus.CREATED);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>当使用string类型的时候就和@ResponceBody+@ResponseStatus 相同</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/handle"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ResponseEntity&lt;String&gt; <span class="title">handle</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    URI location = ...;</span><br><span class="line">    <span class="keyword">return</span> ResponseEntity.created(location).header(<span class="string">"MyResponseHeader"</span>,  <span class="string">"MyValue"</span>).body(<span class="string">"Hello World"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>(3)afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法，该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。该方法将在整个请求结束之后，也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyHandlerInterceptor</span> <span class="keyword">implements</span> <span class="title">HandlerInterceptor</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">preHandle</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Object handler)</span> <span class="keyword">throws</span> Exception </span>&#123; <span class="keyword">return</span> <span class="keyword">false</span>; &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">postHandle</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)</span> <span class="keyword">throws</span> Exception </span>&#123; &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterCompletion</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)</span> <span class="keyword">throws</span> Exception </span>&#123; &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>除了实现HandlerInterceptor可以实现拦截器之外，使用WebRequestInterceptor 同样可以实现拦截器</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyWebHandlerInterceptor</span> <span class="keyword">implements</span> <span class="title">WebRequestInterceptor</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">preHandle</span><span class="params">(WebRequest request)</span> <span class="keyword">throws</span> Exception </span>&#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">postHandle</span><span class="params">(WebRequest request, ModelMap model)</span> <span class="keyword">throws</span> Exception </span>&#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterCompletion</span><span class="params">(WebRequest request, Exception ex)</span> <span class="keyword">throws</span> Exception </span>&#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>(1)preHandle(WebRequest request) 方法。注意这个方法没有返回直，一般主要用它来进行资源的准备工作，其中的webrequest参数是HttpServletRequest的加强版，可以使用setAttribute(name, value, scope)添加参数到指定的作用域中，scope参数有如下的几个值：</p>
<pre><code>1. SCOPE_REQUEST ：它的值是0 ，代表只有在request 中可以访问。
2. SCOPE_SESSION ：它的值是1 ，如果环境允许的话它代表的是一个局部的隔离的session，否则就代表普通的session，并且在该session范围内可以访问。
3. SCOPE_GLOBAL_SESSION ：它的值是2 ，如果环境允许的话，它代表的是一个全局共享的session，否则就代表普通的session，并且在该session 范围内可以访问。
</code></pre><p>(2)postHandle(WebRequest request, ModelMap model) 方法。该方法将在请求处理之后，也就是在Controller 方法调用之后被调用，但是会在视图返回被渲染之前被调用，request 就是传递的请求参数，model就是返回的视图<br>(3)afterCompletion(WebRequest request, Exception ex) 方法。该方法会在整个请求处理完成，也就是在视图返回并被渲染之后执行。所以在该方法中可以进行资源的释放操作。而WebRequest 参数就可以把我们在preHandle 中准备的资源传递到这里进行释放。Exception 参数表示的是当前请求的异常对象，如果在Controller 中抛出的异常已经被Spring 的异常处理器给处理了的话，那么这个异常对象就是是null 。</p>
<p>####HandlerExceptionResolver springmvc 异常处理</p>
<p>异常处理用于处理@controll 这种接口抛出的各种异常，主要有如下的几种  </p>
<ol>
<li><p>SimpleMappingExceptionResolver 异常类名称和错误视图名称之间的映射。用于在浏览器应用程序中呈现错误页面。</p>
</li>
<li><p>DefaultHandlerExceptionResolver 解决Spring MVC引发的异常并将它们映射到HTTP状态代码。另请参阅备用ResponseEntityExceptionHandler和REST API例外。</p>
</li>
<li><p>ResponseStatusExceptionResolver 根据@ResponseStatus注释中的值解决注释中的异常并将其映射到HTTP状态代码。</p>
</li>
<li><p>ExceptionHandlerExceptionResolver 通过调用@ExceptionHandler一个@Controller或一个 @ControllerAdvice类中的方法来解决异常。请参阅@ExceptionHandler方法。</p>
</li>
</ol>
<p>对于异常处理来说通常的解决结果有如下的几种方法</p>
<ol>
<li><p>使用ModelAndView 指向错误视图。</p>
</li>
<li><p>返回空的modelandview 如果异常被处理</p>
</li>
<li><p>如果异常没有被解决，将会使用异常调用连进行处理，如果调用到最后将会抛出到servlet中</p>
</li>
</ol>
<p>在spring mvc 中集中进行异常处理的有三种方法</p>
<ol>
<li>使用@ResponseStatus 注释一个异常类，当spring中抛出这个异常的时候将会自动的交由这个类处理,并且可以制定http code值，比如下面的方法将会跑出403错误</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zj.exception;</span><br><span class="line"><span class="keyword">import</span> org.springframework.http.HttpStatus;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.ResponseStatus;</span><br><span class="line"><span class="meta">@ResponseStatus</span>(value=HttpStatus.FORBIDDEN,reason=<span class="string">"用户不匹配"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserNotMatchException</span> <span class="keyword">extends</span> <span class="title">RuntimeException</span></span>&#123;&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/testResponseStatus"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">testResponseStatus</span><span class="params">(<span class="keyword">int</span> i)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(i==<span class="number">0</span>)</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> UserNotMatchException();</span><br><span class="line">    <span class="keyword">return</span> <span class="string">"hello"</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>注意如果这个注解使用在 一个方法上的时候 ， 不论结果如何都将会放回制定的httpcode 异常</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ResponseStatus</span>(value=HttpStatus.FORBIDDEN,reason=<span class="string">"用户名不匹配"</span>)</span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/testResponseStatus"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">testResponseStatus</span><span class="params">(<span class="keyword">int</span> i)</span></span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(i==<span class="number">0</span>)</span><br><span class="line">        <span class="keyword">throw</span> <span class="keyword">new</span> UserNotMatchException();</span><br><span class="line">    <span class="keyword">return</span> <span class="string">"hello"</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>2.@ControllerAdvice 和 @ExceptionHandler</p>
<p>这两个注解同样用于异常处理</p>
<p>（1）@ExceptionHandler 当一个Controller中有方法加了@ExceptionHandler之后，这个Controller其他方法中没有捕获的异常就会以参数的形式传入加了@ExceptionHandler注解的那个方法中。<strong>注意这个方法要有一个参数，这个参数就是指定要处理的异常</strong></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Created by liuruijie.</span></span><br><span class="line"><span class="comment"> * 处理异常的类，需要处理异常的Controller直接继承这个类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BaseController</span> </span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 处理Controller抛出的异常</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> e 异常实例</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> Controller层的返回值</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@ExceptionHandler</span></span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> Object <span class="title">expHandler</span><span class="params">(Exception e)</span></span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(e <span class="keyword">instanceof</span> SystemException)&#123;</span><br><span class="line">            SystemException ex= (SystemException) e;</span><br><span class="line">            <span class="keyword">return</span> WebResult.buildResult().status(ex.getCode())</span><br><span class="line">                            .msg(ex.getMessage());</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">            <span class="keyword">return</span> WebResult.buildResult().status(Config.FAIL)</span><br><span class="line">                            .msg(<span class="string">"系统错误"</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>（2）@ControllerAdvice  实现这个注解的类可以让这个类中 @ExceptionHandler标记的方法实现全觉异常监听</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@ControllerAdvice</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">GlobalExceptionHandler</span> </span>&#123;</span><br><span class="line">   <span class="comment">//处理自定义的异常</span></span><br><span class="line">   <span class="meta">@ExceptionHandler</span>(SystemException.class) </span><br><span class="line">   <span class="meta">@ResponseBody</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> Object <span class="title">customHandler</span><span class="params">(SystemException e)</span></span>&#123;</span><br><span class="line">      e.printStackTrace();</span><br><span class="line">      <span class="keyword">return</span> WebResult.buildResult().status(e.getCode()).msg(e.getMessage());</span><br><span class="line">   &#125;</span><br><span class="line">   <span class="comment">//其他未处理的异常</span></span><br><span class="line">   <span class="meta">@ExceptionHandler</span>(Exception.class)</span><br><span class="line">   <span class="meta">@ResponseBody</span></span><br><span class="line">   <span class="function"><span class="keyword">public</span> Object <span class="title">exceptionHandler</span><span class="params">(Exception e)</span></span>&#123;</span><br><span class="line">      e.printStackTrace();</span><br><span class="line">      <span class="keyword">return</span> WebResult.buildResult().status(Config.FAIL).msg(<span class="string">"系统错误"</span>);</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>最后对于springmvc 如果异常没有被处理，spring提供了默认的页面展示异常，使用如下方法配置<br>xml ： 制定默认错误页面<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">error-page</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">location</span>&gt;</span>/error<span class="tag">&lt;/<span class="name">location</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">error-page</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<p> java ： 处理url<br> <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ErrorController</span> </span>&#123;</span><br><span class="line">    <span class="meta">@RequestMapping</span>(path = <span class="string">"/error"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Map&lt;String, Object&gt; <span class="title">handle</span><span class="params">(HttpServletRequest request)</span> </span>&#123;</span><br><span class="line">        Map&lt;String, Object&gt; map = <span class="keyword">new</span> HashMap&lt;String, Object&gt;();</span><br><span class="line">        map.put(<span class="string">"status"</span>, request.getAttribute(<span class="string">"javax.servlet.error.status_code"</span>));</span><br><span class="line">        map.put(<span class="string">"reason"</span>, request.getAttribute(<span class="string">"javax.servlet.error.message"</span>));</span><br><span class="line">        <span class="keyword">return</span> map;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h4 id="ViewResolver-提供了view-名称到view实例之间的绑定，并且完成真正视图展示之前将相关数据进行整理的功能"><a href="#ViewResolver-提供了view-名称到view实例之间的绑定，并且完成真正视图展示之前将相关数据进行整理的功能" class="headerlink" title="ViewResolver 提供了view 名称到view实例之间的绑定，并且完成真正视图展示之前将相关数据进行整理的功能"></a>ViewResolver 提供了view 名称到view实例之间的绑定，并且完成真正视图展示之前将相关数据进行整理的功能</h4><p>spring mvc 中将相关的视图变成一个网页经历的过程</p>
<ol>
<li>将SpringMVC控制器中的返回结果封装成一个ModelAndView对象。</li>
<li>通过SpringMVC中的视图解析器，使用ViewResolver对控制器返回的ModelAndView对象进行解析，将逻辑视图转换成物理视图。</li>
<li>调用View中的render()方法对物理视图进行渲染。</li>
</ol>
<p>几个主要的视图的介绍</p>
<ol>
<li>AbstractCachingViewResolver: 最抽象的类提供了视图缓存的功能</li>
<li>UrlBasedViewResolver: 提供了更加细粒度的url控制，支持前缀后缀等功能，但是使用这个方法必须制定相关的view解析工具，默认使用的是jsp解析工具InternalResourceView（和可以使用其他的是解析工具比如FreeMarkerView等）， 并且提供了重定向和转发的功能</li>
</ol>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">bean</span>  </span></span><br><span class="line"><span class="tag">   <span class="attr">class</span>=<span class="string">"org.springframework.web.servlet.view.UrlBasedViewResolver"</span>&gt;</span>  </span><br><span class="line">   <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"prefix"</span> <span class="attr">value</span>=<span class="string">"/WEB-INF/"</span> /&gt;</span>  </span><br><span class="line">   <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"suffix"</span> <span class="attr">value</span>=<span class="string">".jsp"</span> /&gt;</span>  </span><br><span class="line">   <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"viewClass"</span> <span class="attr">value</span>=<span class="string">"org.springframework.web.servlet.view.InternalResourceView"</span>/&gt;</span>  </span><br><span class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></span><br></pre></td></tr></table></figure>
<ol start="3">
<li>InternalResourceViewResolver：这个方法是 UrlBasedViewResolver 的子类，支持父类的所有功能，InternalResourceViewResolver会把返回的视图名称都解析为InternalResourceView对象，内部使用重定向的方法，将controller返回的view 包装成InternalResourceView， 并且鞋带上前缀和后缀，同时再转发出去</li>
</ol>
<p>视图解析链：<br>在SpringMVC中可以同时定义多个ViewResolver视图解析器，然后它们会组成一个ViewResolver链。当Controller处理器方法返回一个逻辑视图名称后，ViewResolver链将根据其中ViewResolver的优先级来进行处理。所有的ViewResolver都实现了Ordered接口，在Spring中实现了这个接口的类都是可以排序的。在ViewResolver中是通过order属性来指定顺序的，默认都是最大值。所以我们可以通过指定ViewResolver的order属性来实现ViewResolver的优先级，order属性是Integer类型，order越小，对应的ViewResolver将有越高的解析视图的权利，所以第一个进行解析的将是ViewResolver链中order值最小的那个。当一个ViewResolver在进行视图解析后返回的View对象是null的话就表示该ViewResolver不能解析该视图，这个时候如果还存在其他order值比它大的ViewResolver就会调用剩余的ViewResolver中的order值最小的那个来解析该视图，依此类推。当ViewResolver在进行视图解析后返回的是一个非空的View对象的时候，就表示该ViewResolver能够解析该视图，那么视图解析这一步就完成了，后续的ViewResolver将不会再用来解析该视图。当定义的所有ViewResolver都不能解析该视图的时候，Spring就会抛出一个异常。</p>
<h3 id="spring-mvc-常用注解"><a href="#spring-mvc-常用注解" class="headerlink" title="spring mvc 常用注解"></a>spring mvc 常用注解</h3><p>spring 提供了一整套注解来简化spring相关的配置</p>
<h4 id="Controll-和-RestController"><a href="#Controll-和-RestController" class="headerlink" title="@Controll 和 @RestController"></a>@Controll 和 @RestController</h4><p>Spring MVC提供了一种基于注释的编程模型，其中@Controller和@RestController组件使用注释来表示请求映射，请求输入，异常处理等。</p>
<p>其中的@RestController 是@ResponseBody和@Controller注解的一种集合。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Target</span>(ElementType.TYPE)</span><br><span class="line"><span class="meta">@Retention</span>(RetentionPolicy.RUNTIME)</span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="meta">@ResponseBody</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> RestController &#123;</span><br><span class="line">	<span class="meta">@AliasFor</span>(annotation = Controller.class)</span><br><span class="line">	<span class="function">String <span class="title">value</span><span class="params">()</span> <span class="keyword">default</span> ""</span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>注意：如果使用aop方法对controller 进行增强的话请使用class-based proxying代理，但是如果使用了非spring context回调接口的方法的时候，需要明确的制定相关的配置信息：<a href="tx:annotation-driven/" target="_blank" rel="noopener">tx:annotation-driven/</a>, 改变为 &lt;tx:annotation-driven proxy-target-class=”true”/&gt;.</p>
<h4 id="RequestMapping"><a href="#RequestMapping" class="headerlink" title="@RequestMapping"></a>@RequestMapping</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Target</span>(&#123;ElementType.METHOD, ElementType.TYPE&#125;)</span><br><span class="line"><span class="meta">@Retention</span>(RetentionPolicy.RUNTIME)</span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="meta">@Mapping</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> RequestMapping &#123;</span><br><span class="line">	<span class="function">String <span class="title">name</span><span class="params">()</span> <span class="keyword">default</span> ""</span>;</span><br><span class="line">	<span class="meta">@AliasFor</span>(<span class="string">"path"</span>)</span><br><span class="line">	String[] value() <span class="keyword">default</span> &#123;&#125;;</span><br><span class="line">	<span class="meta">@AliasFor</span>(<span class="string">"value"</span>)<span class="comment">//这个注解和path 标志制定的url地址，可以使用resulf请求的格式</span></span><br><span class="line">    <span class="comment">//spring-web/&#123;symbolicName:[a-z-]+&#125;-&#123;version:\d\.\d\.\d&#125;.&#123;extension:\.[a-z]&#125;</span></span><br><span class="line">	String[] path() <span class="keyword">default</span> &#123;&#125;;</span><br><span class="line">	RequestMethod[] method() <span class="keyword">default</span> &#123;&#125;;<span class="comment">//制定请求的方法，RequestMethod.DELETE</span></span><br><span class="line">	String[] params() <span class="keyword">default</span> &#123;&#125;;<span class="comment">//表示制定的请求参数中存在的参数组合，如myParam = myValue，表示给定的参数为指定的值才会返回</span></span><br><span class="line">    <span class="comment">//可以使用name ！= value 表示不等于的关系</span></span><br><span class="line">	String[] headers() <span class="keyword">default</span> &#123;&#125;;<span class="comment">// 制定头部包含的相关信息和上面的params类似，Referer=http://www.ifeng.com</span></span><br><span class="line">	String[] produces() <span class="keyword">default</span> &#123;&#125;;<span class="comment">//指定返回的内容类型，仅当request请求头中的(Accept)类型中包含该指定类型才返回，表示浏览器接受的相关资源</span></span><br><span class="line">    String[] consumes() <span class="keyword">default</span> &#123;&#125;;<span class="comment">//指定处理请求的提交内容类型（Content-Type），例如application/json, text/html</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>requestMapping:有简化版的各种注解@GetMapping，@PostMapping，@PutMapping，@DeleteMapping，@PatchMapping，指定了相关的method方法对应的各种请求</p>
<p>request 请求可以接受的请求可以通过通配符或者glob参数的方法进行匹配</p>
<p>spring mvc 的地址匹配方法满足一定的相关原则，可以使用通配符进行匹配</p>
<table>
<thead>
<tr>
<th>Wildcard</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>？</td>
<td>匹配任何单字符</td>
</tr>
<tr>
<td>*</td>
<td>匹配0或者任意数量的字符</td>
</tr>
<tr>
<td>**</td>
<td>匹配0或者更多的目录</td>
</tr>
</tbody>
</table>
<p>注意：spring将会按照匹配的字符最长的那个进行匹配，比如/*<em>/</em>.jsp 和/app/dir/*.jsp，在这个过程中，将会匹配后者。</p>
<p>注意：spring mvc 的匹配原则是按照后缀匹配的原则，比如一个url地址 /name这个地址，表示的就是/name.*，一定程度上实现了文件扩展名引用</p>
<p>如果使用了文件扩展名称这种东西如果想要配置请查看如下两个接口：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">useSuffixPatternMatching(<span class="keyword">false</span>), see PathMatchConfigurer</span><br><span class="line">favorPathExtension(<span class="keyword">false</span>), see ContentNeogiationConfigurer</span><br></pre></td></tr></table></figure>
<h5 id="在requestMethod中可以接收的数据"><a href="#在requestMethod中可以接收的数据" class="headerlink" title="在requestMethod中可以接收的数据"></a>在requestMethod中可以接收的数据</h5><p>接受的函数体中可以使用的注解和参数</p>
<ol>
<li>WebRequest, NativeWebRequest</li>
</ol>
<p>WebRequest是Spring Web MVC提供的统一请求访问接口，不仅仅可以访问请求相关数据（如参数区数据、请求头数据，但访问不到Cookie区数据），还可以访问会话和上下文中的数据；NativeWebRequest继承了WebRequest，并提供访问本地Servlet API的方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> String <span class="title">webRequest</span><span class="params">(WebRequest webRequest, NativeWebRequest nativeWebRequest)</span> </span>&#123;</span><br><span class="line">    System.out.println(webRequest.getParameter(<span class="string">"test"</span>));<span class="comment">//①得到请求参数test的值  </span></span><br><span class="line">    webRequest.setAttribute(<span class="string">"name"</span>, <span class="string">"value"</span>, WebRequest.SCOPE_REQUEST);<span class="comment">//②  </span></span><br><span class="line">    System.out.println(webRequest.getAttribute(<span class="string">"name"</span>, WebRequest.SCOPE_REQUEST));</span><br><span class="line">    HttpServletRequest request =</span><br><span class="line">            nativeWebRequest.getNativeRequest(HttpServletRequest.class);<span class="comment">//③  </span></span><br><span class="line">    HttpServletResponse response =</span><br><span class="line">            nativeWebRequest.getNativeResponse(HttpServletResponse.class);</span><br><span class="line">    <span class="keyword">return</span> <span class="string">"success"</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol start="2">
<li>javax.servlet.ServletRequest, javax.servlet.ServletResponse，javax.servlet.http.HttpSession</li>
</ol>
<p>javax 提供的具体接口注意其中的httpsession ，会话访问不是线程安全的。如果允许多个请求同时访问会话，请考虑将RequestMappingHandlerAdapter的“synchronizeOnSession”标志设置为“true”。</p>
<ol start="3">
<li>HttpMethod </li>
</ol>
<p>这个值中有传入的方式，比如get还是post</p>
<ol start="4">
<li>java.io.InputStream, java.io.Reader，java.io.OutputStream, java.io.Writer</li>
</ol>
<p>请求的原始请求数据流，和原始返回数据</p>
<ol start="5">
<li>@PathVariable和@MatrixVariable</li>
</ol>
<p>使用{}表示的url请求对应的相关参数,</p>
<p>@PathVariable 没什么好说的关键是@MatrixVariable ， 这个注解将会自动的匹配url 地址中 ;uuu=123;iii=333 这种参数，并且一定的程度下并不需要{jj}中指定的名称来匹配，当发生参数冲突的时候可以使用pathVar参数指定名称，目前有bug不记录了</p>
<ol start="5">
<li>@PathVariable,@MatrixVariable,@RequestParam，@RequestBody，@RequestHeader，@CookieValue，@RequestPart,@ModelAttribute,@SessionAttribute,@RequestAttribute</li>
</ol>
<ul>
<li>@PathVariable ,spring mvc提供了一套支持reastfulapi的方法，这套方法可以使用{}+通配符的方式，将url中的数据传递到method 对应的参数中</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@GetMapping</span>(<span class="string">"/owners/&#123;ownerId&#125;/pets/&#123;petId&#125;"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> Pet <span class="title">findPet</span><span class="params">(@PathVariable Long ownerId, @PathVariable Long petId)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 可以使用这个方法实现全局的请求效果</span></span><br><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/owners/&#123;ownerId&#125;"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">OwnerController</span> </span>&#123;</span><br><span class="line">    <span class="meta">@GetMapping</span>(<span class="string">"/pets/&#123;petId&#125;"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> Pet <span class="title">findPet</span><span class="params">(@PathVariable Long ownerId, @PathVariable(petId)</span> Long petId) </span>&#123;</span><br><span class="line">        <span class="comment">// ...</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>注意：{}里面的值值也可以使用正则表达式进行相关的配置，格式：{varName:regex}</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@GetMapping</span>(<span class="string">"/&#123;name:[a-z-]+&#125;-&#123;version:\\d\\.\\d\\.\\d&#125;&#123;ext:\\.[a-z]+&#125;"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handle</span><span class="params">(@PathVariable String version, @PathVariable String ext)</span> </span>&#123;&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li><p>@MatrixVariable，这个注解将会自动的匹配url地址中;uuu=123;iii=333这种参数，并且一定的程度下并不需要{jj}中指定的名称来匹配，当发生参数冲突的时候可以使用pathVar参数指定名称，目前有bug不记录了</p>
</li>
<li><p>@RequestParam接口将会自动的将传入到指定的地址中 如果使用这个注解标识Map&lt;String, String&gt; or MultiValueMap&lt;String, String&gt;，将会将所有的属性注入进来<br>A） 常用来处理简单类型的绑定，通过Request.getParameter() 获取的String可直接转换为简单类型的情况（ String–&gt; 简单类型的转换操作由ConversionService配置的转换器来完成）；因为使用request.getParameter()方式获取参数，所以可以处理get 方式中queryString的值，也可以处理post方式中 body data的值；<br>B）用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容，提交方式GET、POST；<br>C) 该注解有两个属性： value、required； value用来指定要传入值的id名称，required用来指示参数是否必须绑定；</p>
</li>
<li><p>@RequestBody 该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容，例如application/json, application/xml等；它是通过使用HandlerAdapter 配置的HttpMessageConverters来解析post data body，然后绑定到相应的bean上的。</p>
</li>
</ul>
<p>使用：HttpMessageConverter接口，需要开启&lt;mvc:annotation-driven  /&gt;。 AnnotationMethodHandlerAdapter将会初始化7个转换器，可以通过调用AnnotationMethodHandlerAdapter的getMessageConverts()方法来获取转换器的一个集合 List<httpmessageconverter>，这7个转化器如下：</httpmessageconverter></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">ByteArrayHttpMessageConverter </span><br><span class="line">StringHttpMessageConverter </span><br><span class="line">ResourceHttpMessageConverter </span><br><span class="line">SourceHttpMessageConverter </span><br><span class="line">XmlAwareFormHttpMessageConverter </span><br><span class="line">Jaxb2RootElementHttpMessageConverter </span><br><span class="line">MappingJacksonHttpMessageConverter</span><br></pre></td></tr></table></figure>
<p>PS:Spring默认的json协议解析由Jackson完成。 这种方式的时候默认使用的就是json解析。</p>
<p>问题 如何扩展</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span>  </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">PersonController</span> </span>&#123;    </span><br><span class="line">    <span class="meta">@RequestMapping</span>(value = <span class="string">"/person/login"</span>, method = RequestMethod.POST)  </span><br><span class="line">    <span class="keyword">public</span> <span class="meta">@ResponseBody</span>  </span><br><span class="line">    <span class="function">Person <span class="title">login</span><span class="params">(@RequestBody Person person)</span> </span>&#123;  </span><br><span class="line">        <span class="keyword">return</span> person;  </span><br><span class="line">    &#125;  </span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//注意序列化接口</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person</span> <span class="keyword">implements</span> <span class="title">Serializable</span> </span>&#123;  </span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> id;  </span><br><span class="line">    <span class="keyword">private</span> String name;  </span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">boolean</span> status;  </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Person</span><span class="params">()</span> </span>&#123;  </span><br><span class="line">        <span class="comment">// do nothing  </span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>ps：如果使用xml 方式，需要使用注解</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@XmlRootElement</span>(name = <span class="string">"Person"</span>)</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Person</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">int</span> age;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span> </span>&#123; <span class="keyword">return</span> name;    &#125;</span><br><span class="line">    <span class="meta">@XmlElement</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setName</span><span class="params">(String name)</span> </span>&#123; <span class="keyword">this</span>.name = name;    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getAge</span><span class="params">()</span> </span>&#123; <span class="keyword">return</span> age;    &#125;</span><br><span class="line">    <span class="meta">@XmlElement</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAge</span><span class="params">(<span class="keyword">int</span> age)</span> </span>&#123; <span class="keyword">this</span>.age = age;    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>注意 这里如果要使用注意spring mvc 环境的配置</p>
<p>使用xml 进行配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">context:annotation-config</span>&gt;</span><span class="tag">&lt;/<span class="name">context:annotation-config</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">"com"</span>&gt;</span><span class="tag">&lt;/<span class="name">context:component-scan</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">mvc:annotation-driven</span>&gt;</span><span class="tag">&lt;/<span class="name">mvc:annotation-driven</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">mvc:default-servlet-handler</span>/&gt;</span></span><br></pre></td></tr></table></figure>
<p>使用java 进行配置</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//注意要将sevlet放入 WebApplicationContext中</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyWebApplication</span> <span class="keyword">implements</span> <span class="title">WebApplicationInitializer</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onStartup</span><span class="params">(ServletContext servletContext)</span> <span class="keyword">throws</span> ServletException </span>&#123;</span><br><span class="line">        AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext=</span><br><span class="line">                <span class="keyword">new</span> AnnotationConfigWebApplicationContext();</span><br><span class="line">        annotationConfigWebApplicationContext.register(AppConfig.class);</span><br><span class="line">        annotationConfigWebApplicationContext.setServletContext(servletContext);</span><br><span class="line">        annotationConfigWebApplicationContext.refresh();</span><br><span class="line">        ServletRegistration.Dynamic dynamic=servletContext.addServlet(<span class="string">"dispatcher"</span>,<span class="keyword">new</span> DispatcherServlet(annotationConfigWebApplicationContext));</span><br><span class="line">        dynamic.setLoadOnStartup(<span class="number">1</span>);</span><br><span class="line">        dynamic.addMapping(<span class="string">"/"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//自动化配置</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@ComponentScan</span></span><br><span class="line"><span class="meta">@EnableWebMvc</span><span class="comment">//使用EnableWebMVC注解自动的注入的相关的属性</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">AppConfig</span>  </span>&#123; &#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>@RequestPart  和文件上传相关，难度有点大，和http协议相关的暂时不考虑</li>
</ul>
<ul>
<li><p>@RequestHeader 将http协议中相关的头注入到指定的数据中</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@GetMapping</span>(<span class="string">"/demo"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handle</span><span class="params">(</span></span></span><br><span class="line"><span class="function"><span class="params">        @RequestHeader(<span class="string">"Accept-Encoding"</span>)</span> String encoding,</span></span><br><span class="line"><span class="function">        @<span class="title">RequestHeader</span><span class="params">(<span class="string">"Keep-Alive"</span>)</span> <span class="keyword">long</span> keepAlive) </span>&#123;</span><br><span class="line">    <span class="comment">//...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>@ModelAttribute</p>
</li>
</ul>
<p>在使用model view 场景下，有如下的一应用</p>
<ul>
<li><ol>
<li>全局model配置，在获得请求/helloWorld 后，populateModel方法在helloWorld方法之前先被调用，它把请求参数（/helloWorld?abc=text）加入到一个名为attributeName的model属性中，在它执行后 helloWorld被调用，返回视图名helloWorld和model已由@ModelAttribute方法生产好了。<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span> </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloWorldController</span> </span>&#123; </span><br><span class="line">    <span class="meta">@ModelAttribute</span> </span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">populateModel</span><span class="params">(@RequestParam String abc, Model model)</span> </span>&#123; </span><br><span class="line">         model.addAttribute(<span class="string">"attributeName"</span>, abc); </span><br><span class="line">    &#125; </span><br><span class="line">    <span class="meta">@ModelAttribute</span>(<span class="string">"attributeName"</span>) </span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">addAccount</span><span class="params">(@RequestParam String abc)</span> </span>&#123; </span><br><span class="line">        <span class="keyword">return</span> abc; </span><br><span class="line">    &#125; </span><br><span class="line">    <span class="meta">@RequestMapping</span>(value = <span class="string">"/helloWorld"</span>) </span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">helloWorld</span><span class="params">()</span> </span>&#123; </span><br><span class="line">       <span class="keyword">return</span> <span class="string">"helloWorld"</span>; </span><br><span class="line">    &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
</li>
</ol>
</li>
<li><ol start="2">
<li>指派model配置  返回 helloworld.do视图，有一个model 参数是attributeName和值 hi</li>
</ol>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span> </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloWorldController</span> </span>&#123; </span><br><span class="line">    <span class="meta">@RequestMapping</span>(value = <span class="string">"/helloWorld.do"</span>) </span><br><span class="line">    <span class="meta">@ModelAttribute</span>(<span class="string">"attributeName"</span>) </span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">helloWorld</span><span class="params">()</span> </span>&#123; </span><br><span class="line">        <span class="keyword">return</span> <span class="string">"hi"</span>; </span><br><span class="line">    &#125; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li><ol start="3">
<li>绑定application/x-www-form-urlencoded 提交的请求中 的值到对象中 支持user.xxx,user2.ddd 嵌套对应法</li>
</ol>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span> </span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">HelloWorldController</span> </span>&#123; </span><br><span class="line">    <span class="meta">@RequestMapping</span>(value = <span class="string">"/helloWorld"</span>) </span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">helloWorld</span><span class="params">(@ModelAttribute User user)</span> </span>&#123; </span><br><span class="line">        <span class="keyword">return</span> <span class="string">"helloWorld"</span>; </span><br><span class="line">     &#125; </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>@CookieValue  和之前的相同，就是将cookie中相关的数据拿出来</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@GetMapping</span>(<span class="string">"/demo"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handle</span><span class="params">(@CookieValue(<span class="string">"JSESSIONID"</span>)</span> String cookie) </span>&#123;&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>HttpEntity<b> HttpEntity或多或少与使用@RequestBody相同，但基于公开请求标头和主体的容器对象。</b></li>
</ul>
<p>注意这个方法多是用于post请求用来针对ajax序列化的json对象解析，其中有一个getbody方法</p>
 <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostMapping</span>(<span class="string">"/accounts"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handle</span><span class="params">(HttpEntity&lt;Account&gt; entity)</span> </span>&#123;</span><br><span class="line">    Account account=entity.getBody();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>@InitBinder  spring自带的数据处理模块</li>
</ul>
<p>由@InitBinder表示的方法，可以对WebDataBinder对象进行初始化。WebDataBinder是DataBinder的子类，用于完成由表单到JavaBean属性的绑定。<br>@InitBinder方法不能有返回值，它必须盛名为void。<br>@InitBinder方法的参数通常是WebDataBinder，@InitBinder可以对WebDataBinder进行初始化。</p>
<p>注意这个注解只是针对这个controller中的方法起作用，无法针对所有的controller</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BinderAction</span> </span>&#123;</span><br><span class="line">    <span class="meta">@RequestMapping</span>(<span class="string">"/sb2.do"</span>)</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doTest</span><span class="params">(@RequestParam(value=<span class="string">"name"</span>)</span>String name,@<span class="title">RequestParam</span><span class="params">(value=<span class="string">"age"</span>)</span><span class="keyword">double</span> age,@<span class="title">RequestParam</span><span class="params">(value=<span class="string">"nowTime"</span>)</span>Date nowTime)</span>&#123;</span><br><span class="line">        System.err.println(<span class="string">"name:"</span> + name);</span><br><span class="line">        System.err.println(<span class="string">"age:"</span> + age);</span><br><span class="line">        System.err.println(<span class="string">"nowTime:"</span> + nowTime);</span><br><span class="line">    &#125;    </span><br><span class="line">    <span class="meta">@InitBinder</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">initBinder</span><span class="params">(WebDataBinder binder)</span></span>&#123;</span><br><span class="line">        binder.registerCustomEditor(Date.class, <span class="keyword">new</span> CustomDateEditor(<span class="keyword">new</span> SimpleDateFormat(<span class="string">"yyyy-MM-dd"</span>), <span class="keyword">true</span>));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@InitBinder</span></span><br><span class="line">    <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">initBinder</span><span class="params">(WebDataBinder binder)</span> </span>&#123;</span><br><span class="line">        binder.addCustomFormatter(<span class="keyword">new</span> DateFormatter(<span class="string">"yyyy-MM-dd"</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>注意WebDataBinder这个对象，这个对象拥有一个方法registerCustomEditor,这个方法将会自动的配置属性映射器，将相关的属性映射到指定的位置，属性映射器可以使用如下的方法进行自定义<br>实现PropertyEditor或者重写PropertyEditorSupport对象中的方法，注意这种方法只能实现string到对象的转换 setValue中就是转化后的对象，setAsText传入的就是传入的url字符串</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//实现PropertyEditor或者重写PropertyEditorSupport对象中的方法</span></span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.propertyeditors.PropertiesEditor;</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DoubleEditor</span> <span class="keyword">extends</span> <span class="title">PropertyEditorSupport</span> </span>&#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAsText</span><span class="params">(String text)</span> <span class="keyword">throws</span> IllegalArgumentException </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (text == <span class="keyword">null</span> || text.equals(<span class="string">""</span>)) &#123;</span><br><span class="line">            text = <span class="string">"0"</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        setValue(Double.parseDouble(text));</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getAsText</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> getValue().toString();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>同时WebDataBinder这个对象，这个对象拥有一个addCustomFormatter 可以直接使用formatter进行参数转化本质上是相同的</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@InitBinder</span></span><br><span class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">initBinder</span><span class="params">(WebDataBinder binder)</span> </span>&#123;</span><br><span class="line">    binder.addCustomFormatter(<span class="keyword">new</span> DateFormatter(<span class="string">"yyyy-MM-dd"</span>));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>addCustomFormatter本质上还是和registerCustomEditor是一样的见源代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addCustomFormatter</span><span class="params">(Formatter&lt;?&gt; formatter)</span> </span>&#123;</span><br><span class="line">	FormatterPropertyEditorAdapter adapter = <span class="keyword">new</span> FormatterPropertyEditorAdapter(formatter);</span><br><span class="line">	getPropertyEditorRegistry().registerCustomEditor(adapter.getFieldType(), adapter);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h4 id="RequestMapping-方法返回值中的参数"><a href="#RequestMapping-方法返回值中的参数" class="headerlink" title="@RequestMapping 方法返回值中的参数"></a>@RequestMapping 方法返回值中的参数</h4><ol>
<li>@ResponseBody</li>
</ol>
<ol start="2">
<li>HttpEntity<b>, ResponseEntity<b></b></b></li>
</ol>
<ul>
<li><p>HttpEntity<b> HttpEntity或多或少与使用@RequestBody相同，但基于公开请求标头和主体的容器对象。</b></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@PostMapping</span>(<span class="string">"/accounts"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">handle</span><span class="params">(HttpEntity&lt;Account&gt; entity)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>ResponseEntity<b> 这个类其实是对 http请求的一个封装，封装了http的报头，状态码，http code 等数据，本质上是一种通信协议</b></p>
</li>
</ul>
<p>如果使用的不是string类型，那么将会是一种类似rpc协议</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//客户端</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">client</span><span class="params">()</span></span>&#123;</span><br><span class="line">    RestTemplate restTemplate = <span class="keyword">new</span> RestTemplate();</span><br><span class="line">    ResponseEntity&lt;String&gt; entity = restTemplate.getForEntity(<span class="string">"http://example.com"</span>, String.class);</span><br><span class="line">    String body = entity.getBody();</span><br><span class="line">    MediaType contentType = entity.getHeaders().getContentType();</span><br><span class="line">    HttpStatus statusCode = entity.getStatusCode();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//服务端</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/handle"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ResponseEntity&lt;String&gt; <span class="title">handle</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    URI location = ...;</span><br><span class="line">    HttpHeaders responseHeaders = <span class="keyword">new</span> HttpHeaders();</span><br><span class="line">    responseHeaders.setLocation(location);</span><br><span class="line">    responseHeaders.set(<span class="string">"MyResponseHeader"</span>, <span class="string">"MyValue"</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> ResponseEntity&lt;String&gt;(<span class="string">"Hello World"</span>, responseHeaders,   HttpStatus.CREATED);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>当使用string类型的时候就和@ResponceBody+@ResponseStatus 相同</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/handle"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ResponseEntity&lt;String&gt; <span class="title">handle</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    URI location = ...;</span><br><span class="line">    <span class="keyword">return</span> ResponseEntity.created(location).header(<span class="string">"MyResponseHeader"</span>,  <span class="string">"MyValue"</span>).body(<span class="string">"Hello World"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol start="3">
<li>HttpHeaders</li>
</ol>
<p>返回一个封装的httpheaders的头，这个类有一个set方法，制定方法的头和内容，如果想深入的使用，需要精通http协议</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> HttpHeaders <span class="title">getHeader</span><span class="params">()</span></span>&#123;</span><br><span class="line">    HttpHeaders httpHeaders = <span class="keyword">new</span> HttpHeaders();</span><br><span class="line">    <span class="keyword">return</span> httpHeaders;   </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ol start="4">
<li>string</li>
</ol>
<p>最简单的一个方法，spring将会使用这个字符串找到对应的view</p>
<ol start="5">
<li>java.util.Map, org.springframework.ui.Model，@ModelAttribute</li>
</ol>
<p>spring mvc modelandview体系的东西</p>
<ol start="6">
<li><p>ResponseBodyEmitter, SseEmitter， StreamingResponseBody</p>
</li>
<li><p>Reactive types — Reactor, RxJava, or others via ReactiveAdapterRegistry</p>
</li>
<li><p>@ResponseStatus(HttpStatus.CREATED)</p>
</li>
</ol>
<p>制定返回值的头部信息, 比如制定401 402 这种http code</p>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2018/10/09/spring5-springMVC使用简介/" rel="next" title="">
                <i class="fa fa-chevron-left"></i> 
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2018/10/09/spring5-springMVC异步请求支持/" rel="prev" title="">
                 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">kyssion</p>
              <p class="site-description motion-element" itemprop="description"></p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">133</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                
                  <span class="site-state-item-count">3</span>
                  <span class="site-state-item-name">分类</span>
                
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                
                  <span class="site-state-item-count">2</span>
                  <span class="site-state-item-name">标签</span>
                
              </div>
            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#spring-MVC-整体的架构设计"><span class="nav-number">1.</span> <span class="nav-text">spring MVC 整体的架构设计</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#web容器的初始化设置"><span class="nav-number">1.1.</span> <span class="nav-text">web容器的初始化设置</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#最核心类-DispatcherServlet"><span class="nav-number">2.</span> <span class="nav-text">最核心类 DispatcherServlet</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Interception-拦截器"><span class="nav-number">3.</span> <span class="nav-text">Interception 拦截器</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#HandlerInterceptor-接口方法"><span class="nav-number">3.1.</span> <span class="nav-text">HandlerInterceptor 接口方法</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#ViewResolver-提供了view-名称到view实例之间的绑定，并且完成真正视图展示之前将相关数据进行整理的功能"><span class="nav-number">3.2.</span> <span class="nav-text">ViewResolver 提供了view 名称到view实例之间的绑定，并且完成真正视图展示之前将相关数据进行整理的功能</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#spring-mvc-常用注解"><span class="nav-number">4.</span> <span class="nav-text">spring mvc 常用注解</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Controll-和-RestController"><span class="nav-number">4.1.</span> <span class="nav-text">@Controll 和 @RestController</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#RequestMapping"><span class="nav-number">4.2.</span> <span class="nav-text">@RequestMapping</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#在requestMethod中可以接收的数据"><span class="nav-number">4.2.1.</span> <span class="nav-text">在requestMethod中可以接收的数据</span></a></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#RequestMapping-方法返回值中的参数"><span class="nav-number">4.3.</span> <span class="nav-text">@RequestMapping 方法返回值中的参数</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2018</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">kyssion</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Mist</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
